/********************************************
 * 
 * 타이틀 : 게임 플레이 화면
 * 기능 : 
 * 작성자 : LJI
 * 작성일 : 2013.09.26
 * 
 ********************************************/

package com.game.pacman.client;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class PlayScreen extends JPanel  implements  Runnable, ActionListener{
	private PlayScreenInfo playScreenInfoP1;
	private PlayScreenInfo playScreenInfoP2;
	private PlayMapScreen mapScreen;
	
	//글자를 표시(drawString)할 때 사용할 폰트 변수
	private Font font; 
	
	//1인용,2인용
	private int playType;
	
	//Monster 객체를 관리하는 컬렉션 
	private ArrayList<Monster> monsters;
	private Player player=null;
	
	//방향을 표시하는 변수
	private int direction;
	
	//점수
	private int score;
	private Rectangle2D r;
	private String finish;  //종료표시문자
	
	private boolean running=false;	//쓰레드 실행 상태
	private boolean gameover=false;	//게임의 종료 상태
	
	Thread thread ;
	
	public PlayScreen() {
		init();
	}
	/**
	 * 화면초기화
	 */
	public void init(){
		setLayout(null);
		setFocusable(true);
		
		font=new Font("Colas", Font.BOLD, 50);
		
		//유저정보1,맵,유저정보2 영역 설정
		playScreenInfoP1 = new PlayScreenInfo(0,0);
		playScreenInfoP2 = new PlayScreenInfo(Constants.BUTTON_WIDTH+Constants.MAP_WIDTH,0);
		mapScreen = new PlayMapScreen();
		add(playScreenInfoP1);
		add(mapScreen);
		add(playScreenInfoP2);
		
//		playType=Constants.P1Type;  //1인용
		playType=Constants.P2Type;  //2인용	
		
		//오브젝트 생성
		player = new Player();
		try {
			//각 게임 객체들이 사용할 이미지를 로딩 (게임 객체들이 공유해서 재사용)
			URL url;	
			Image monsterImage ;
			monsters=new ArrayList<Monster>();
			
			int posX=0,posY=0;
			for(int i=0;i<1;i++){
				url = getClass().getResource(
						String.format("/image/monster%d.png",i+1));		
				monsterImage = ImageIO.read(url);

				//원본 이미지를 화면 크기에 맞게 조정해서 저장
				monsterImage = monsterImage.getScaledInstance(
						Constants.OBJECT_WIDTH, 
						Constants.OBJECT_HEIGHT, 
						Image.SCALE_SMOOTH);				
				switch(i){
					case 0:
						//red monster
						posX=11; posY=9; direction=Constants.UP; break;
						//posX=11; posY=9; direction=5; break;
					case 1:
						//pink monster
						//posX=14; posY=9; direction=Constants.UP; break;
						posX=14; posY=9; direction=5; break;
					case 2:
						//blue monster
						//posX=8; posY=17; direction=Constants.DOWN; break;
						posX=8; posY=17; direction=5; break;
					case 3:
						//yellow monster
						//posX=17; posY=17; direction=Constants.DOWN; break;
						posX=17; posY=17; direction=5; break;
				}
				Monster monster = new Monster(
						monsterImage,
						posX*Constants.OBJECT_WIDTH+Constants.BUTTON_WIDTH,
						posY*Constants.OBJECT_HEIGHT,
						direction);
				monsters.add(monster);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		
		setDoubleBuffered(true);
		
		//키보드 이벤트 수신기 등록 - 게임 객체들의 움직임, 몬스터 발사 등을 처리
		addKeyListener(keyListener);
		
//		startGame();
		
	}

	/**
	 * 게임초기화
	 */
	public void startGame() {
		//System.currentTimeMills() : 현재시간을 long형 데이터로 반환 (밀리세컨드)
		//lastShootingTime = System.currentTimeMillis() - 500;
		//lastStoneCreationTime = System.currentTimeMillis() - 500;
		
//		running = true;
//		gameover = false;
		requestFocus(true);
	
		//화면 프레임 처리를 수행하는 쓰레드 시작
		thread = new Thread(this);
		thread.start();//-> run()
		mapScreen.startGame();
	}
	
	/**
	 * 객체 클릭
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		String strButton =((JButton)e.getSource()).getText();
		switch(strButton){
		case "승리":
			//running=true; gameover=true;
			GameFrame.card.show(GameFrame.mainScreen, Constants.MENU_SCREEN);
			break;
		case "패배":
			//running=false; gameover=true;
			GameFrame.card.show(GameFrame.mainScreen, Constants.MENU_SCREEN);
			break;
		}		
	}

	/** 
	 * 화면의 갱신
	 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		
		Graphics2D g2d = (Graphics2D)g;		

		if (!running && !gameover) {
			gameover = true;			
			repaint();
			
			return;
		}

		//쓰레드도 중지되고 게임도 종료된 경우
		//-> "게임종료" 문자열 출력
		if (gameover) {
			g.setFont(font);
			g.setColor(Color.RED);
			
			if (playType==Constants.P1Type)  //1인용	
				finish="GAME OVER";
			else //2인용
				finish="VICTORY";
			
			//FontMetrics().getStringBounds : 지정된 폰트로 그려진 문자열의 영역 반환
			r= g2d.getFontMetrics().getStringBounds(finish,g2d);
			g2d.drawString(finish,
					(Constants.WINDOW_WIDTH-(int)r.getWidth())/2,
					(Constants.WINDOW_HEIGHT-(int)r.getHeight())/2);
			
			return;
		}
		player.draw(g2d);
		for (Monster monster : monsters) {
			monster.draw(g2d);
		}
	}	
	
	/**
	 * 화면 프레임 처리 쓰레드
	 * 1. update (게임 요소들의 변경사항을 처리 - 데이터 조작)
	 * 2. draw (repaint 호출해서 화면을 다시 그리기)
	 */
	@Override
	public void run() {
		running = true;
		gameloop : while (running) {
//		while(true){
			//update (데이터 변경)
			
			for (Monster monster : monsters) {
				monster.moveStart();
				if (monster.isCrashWall()){  //벽과충돌했으면
					//현위치파악해서 상하좌우에 갈수있는곳 체크
					//진행가능한 방향 확인하고 왔던 방향을 제외한 나머지 방향으로 이동하기					
				}//->해당부분은 클래스에서 처리가능할듯..
				
				if (monster.isCrashPlayer()){  //유저와충돌했으면
					//유저상태가 노말이면 게임종료
					running=false;
					break gameloop;
					//유저상태가 무적이면 초기위치로 이동
					//점수 획득
	
				}				
			}
			
			//draw (그리기)	
			for (Monster monster : monsters) {
				
				if(!monster.findLoad(mapScreen))monster.update();
			}
			
			//player.update();
//			player.setImage(player.isImageState());
			
			
			
			while(true){
				//update (데이터 변경)
				//키입력 후 자동이동
				direction=player.getDirection();
				switch (direction){
					case Constants.LEFT : 
						player.setX(player.getX()-25); break; 
					case Constants.RIGHT : player.setX(player.getX()+25); break;
					case Constants.UP : player.setY(player.getY()-25);break;
					case Constants.DOWN : player.setY(player.getY()+25); break;
				} 
				//draw (그리기)	
				player.update();

			//	player.setImage(player.isImageState());
				
				for (Monster monster : monsters) {
					monster.moveStart();
					monster.update();
				}
			
			repaint();
			
			//데이터통신
			//스코어,몬스터 위치4개, 플레이어위치,플레이어상태(2p인경우)
			
			try {
				Thread.sleep(200);
			} catch (Exception ex) {}
		}
	}
	}
	/**
	 * 키보드 이벤트 수신기
	 * 익명 클래스 객체를 생성해서 이벤트 수신
	 * 기능 : 플레이어의 위치 변경
	 */
	private KeyListener keyListener = new KeyAdapter() {
		@Override
		public void keyPressed(KeyEvent e) {			
			player.keyPressedHandler(e);
			super.keyPressed(e);
		}
		@Override
		public void keyReleased(KeyEvent e) {			
			player.keyReleasedHandler(e);
			super.keyReleased(e);			
		}
	};
}
